﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using TUCAMAPI;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using Eps.Ai.Common;

namespace InfonavaEye
{
    public partial class CameraSettingForm : Form
    {

        public event Action settingCloseDelegate;

        const int PID_MICHROME6 = 0xEC09;
        const int PID_MICHROME20 = 0xEC0B;
        const int PID_MICHROME5PRO = 0xEC07;

        TUCAM_INIT m_itApi;                 // SDK initialize environment object

        int m_pid;                          // The current used camera PID  s
        int m_indexCam;                     // The current used camera index
        List<TUCAM_OPEN> m_opCamList;       // The list of opened cameras object   
        List<TUCAM_DRAW_INIT> m_itDrawList; // The list of drawing object

        UInt64 m_drawingFramesCnt;          // The count of drawing frames
        TimeSpan m_startTime;               // The start time count
        float m_fps;                        // The current frame speed
    
        int m_clientWinWidth;               // The current client window width
        int m_clientWinHeight;              // The current client window height
        TUCAM_DRAW m_drawing;               // The drawing object
        TUCAM_FRAME m_frame;                // The frame which get from SDK
        Thread m_waitingThread;             // The waiting frame thread

        TUCAM_CAPA_ATTR m_resolutionCapa;   // The resolution capability attribute
        TUCAM_CAPA_ATTR m_binningCapa;      // The binning capability attribute
        TUCAM_CAPA_ATTR m_aeCapa;           // The auto exposure capability attribute
        TUCAM_PROP_ATTR m_gainProp;         // The gain property attribute
        TUCAM_PROP_ATTR m_aeTargetProp;     // The auto exposure time target property attribute
        TUCAM_PROP_ATTR m_exposureProp;     // The exposure time property attribute

        TUCAM_CAPA_ATTR m_autoLevelsCapa;   // The auto levels capability attribute
        TUCAM_PROP_ATTR m_leftLevelProp;    // The left level property attribute
        TUCAM_PROP_ATTR m_rightLevelProp;   // The right level property attribute
        TUCAM_PROP_ATTR m_gammaProp;        // The gamma property attribute
        TUCAM_PROP_ATTR m_contrastProp;     // The contrast property attribute
        TUCAM_PROP_ATTR m_sharpnessProp;    // The sharpness property attribute
        TUCAM_PROP_ATTR m_permeabilityProp; // The permeability property attribute

        TUCAM_CAPA_ATTR m_awbCapa;          // The auto white balance capability attribute
        TUCAM_PROP_ATTR m_redChannelProp;   // The red channel property attribute
        TUCAM_PROP_ATTR m_greenChannelProp; // The green channel property attribute
        TUCAM_PROP_ATTR m_blueChannelProp;  // The blue channel property attribute
        TUCAM_PROP_ATTR m_cctProp;          // The color temperature property attribute
        TUCAM_PROP_ATTR m_saturationProp;   // The saturation property attribute
        TUCAM_PROP_ATTR m_hueProp;          // The hue property attribute
        TUCAM_PROP_ATTR m_lightProp;        // The light property attribute

        TUCAM_CAPA_ATTR m_hdrCapa;          // The HDR capability attribute
        TUCAM_CAPA_ATTR m_verticalCapa;     // The vertical capability attribute
        TUCAM_CAPA_ATTR m_horizontalCapa;   // The horizontal capability attribute
        TUCAM_CAPA_ATTR m_monochromeCapa;   // The monochrome capability attribute

        TUCAM_TRIGGER_ATTR m_triggerAttr;   // The trigger parameter attribute

        bool m_isSupportSec;                // Is support sec
        bool m_isSupportMs;                 // Is support ms
        bool m_isSupportAeTarget;           // Is support auto exposure time target
        bool m_isSupportCCT;                // Is support color temperature
        bool m_isSupportBinng;              // Is support binning
        bool m_isWaiting;                   // Is waiting for the image frame
        bool m_isSaving;                    // Is saving the image
        bool m_isRecording;                 // Is recording the video
        bool m_isRoi;                       // Is on ROI mode
        bool m_isTrigger;                   // Is trigger mode

        int m_totalFrames;                  // The saved image total frames
        int m_savedFormat;                  // The format of saved image 
        int m_savedFormatCnt;               // The count of saved image format
        int m_captureTimes;                 // The capture times
        int m_savedFramesCnt;               // The count of saved frames
        int m_savedSucceedCnt;              // The count of image succeed

        string m_filePath;                  // The file path where to save image file and video file
        string m_imageName;                 // The saved image name

        System.Timers.Timer m_aeTimer;              // The auto exposure timer
        System.Timers.Timer m_onceAeTimer;          // The once auto exposure timer
        System.Timers.Timer m_autoLeftLevelsTimer;  // The auto left levels timer
        System.Timers.Timer m_autoRightLevelsTimer; // The auto right levels timer
        System.Timers.Timer m_awbTimer;             // The auto white balance timer
        System.Timers.Timer m_onceWbTimer;          // The once white balance timer

        public delegate void UpdateFpsInvok(string fpsStr);
        public delegate void FinishedCaptureInvok(int savedSucceedCnt);




        public CameraSettingForm()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false; //加载时 取消跨线程检查
        }

        private void SamplePro_Resize(object sender, EventArgs e)
        {
            drawingBox.Refresh();
        }

        public void UpdateFps(string fpsStr)
        {
            labelValueSpeed.Text = fpsStr;
        }

        public void FinishedCapture(int savedSucceedCnt)
        {
            buttonRecord.Enabled = true;
            buttonCapture.Enabled = true;

            buttonCapture.Text = "Capture";
        }

        public void OnTimerAutoExposure(object source, System.Timers.ElapsedEventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                double paramValue = 0;

                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_GLOBALGAIN, ref paramValue, 0))
                {
                    if (m_gainProp.dbValMax > 6)
                    {
                        trackBarGain.Value = (int)paramValue;
                        labelValueGain.Text = trackBarGain.Value.ToString();
                    }
                }

                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_EXPOSURETM, ref paramValue, 0))
                {
                    UpdateExposureTime((UInt64)(paramValue * 1000));
                }
            }
        }

        public void OnTimerOnceAutoExposure(object source, System.Timers.ElapsedEventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                int aeState = 2;
                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATEXPOSURE, ref aeState))
                {
                    if (0 == aeState)
                    {
                        m_onceAeTimer.Stop();

                        double paramValue = 0.0f;

                        if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_GLOBALGAIN, ref paramValue, 0))
                        {
                            if (m_gainProp.dbValMax > 6)
                            {
                                trackBarGain.Value = (int)paramValue;
                                labelValueGain.Text = trackBarGain.Value.ToString();
                            }
                        }

                        if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_EXPOSURETM, ref paramValue, 0))
                        {
                            UpdateExposureTime((UInt64)(paramValue * 1000));
                        }

                        buttonExpOK.Enabled = true;
                        buttonOnceAe.Enabled = true;

                        trackBarTarget.Enabled = false;
                        labelNameTarget.Enabled = false;
                        labelValueTarget.Enabled = false;

                        labelNameSec.Enabled = m_isSupportSec;
                        labelNameMs.Enabled = m_isSupportMs;
                        labelNameUs.Enabled = true;

                        numericUpDownSec.Enabled = m_isSupportSec;
                        numericUpDownMs.Enabled = m_isSupportMs;
                        numericUpDownUs.Enabled = true;
                    }
                }
            }
        }

        public void OnTimerAutoLeftLevels(object source, System.Timers.ElapsedEventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                double paramValue = 0.0f;

                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_LFTLEVELS, ref paramValue, 0))
                {
                    trackBarLeftLevel.Value = (int)paramValue;
                    labelValueLeftLevel.Text = trackBarLeftLevel.Value.ToString();
                }
            }
        }

        public void OnTimerAutoRightLevels(object source, System.Timers.ElapsedEventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                double paramValue = 0.0f;

                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_RGTLEVELS, ref paramValue, 0))
                {
                    trackBarRightLevel.Value = (int)paramValue;
                    labelValueRightLevel.Text = trackBarRightLevel.Value.ToString();
                }
            }
        }

        public void OnTimerUpdateWhiteBalance(object source, System.Timers.ElapsedEventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                double channelValue = 0;
                IntPtr hIdxTUCam = m_opCamList[m_indexCam].hIdxTUCam;

                // Get the current red channel value
                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref channelValue, 1))
                {
                    trackBarRed.Value = (int)channelValue;
                    channelValue /= 2.0f;
                    labelValueRed.Text = channelValue.ToString("#0.0");
                }

                // Get the current green channel value
                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref channelValue, 2))
                {
                    trackBarGreen.Value = (int)channelValue;
                    channelValue /= 2.0f;
                    labelValueGreen.Text = channelValue.ToString("#0.0");
                }

                // Get the current blue channel value
                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref channelValue, 3))
                {
                    trackBarBlue.Value = (int)channelValue;
                    channelValue /= 2.0f;
                    labelValueBlue.Text = channelValue.ToString("#0.0");
                }

                UpdateColorTemperature(m_opCamList[m_indexCam]);
            }
        }

        private void SamplePro_Load(object sender, EventArgs e)
        {
            /* full screen */
            //this.WindowState = FormWindowState.Maximized;

            m_opCamList = new List<TUCAM_OPEN>();
            m_itDrawList = new List<TUCAM_DRAW_INIT>();

            if (TUCAMRET.TUCAMRET_NO_CAMERA == InitApi())
            {
                MessageBox.Show("Please connect the camera.", "Tips");
                return;
            }

            if (TUCAMRET.TUCAMRET_FAILOPEN_CAMERA == OpenAllConnectedCameras())
            {
                MessageBox.Show("Open the opened camera failed!", "Tips");
                return;
            }

            InitAllOpenedCamerasDrawing();

            // Set current selected camera
            m_indexCam = 0;
            m_isSaving = false;
            m_isRecording = false;
            m_clientWinWidth = 0;
            m_clientWinHeight = 0;

            InitAllTimers();
            InitRoiParameter();
            InitParameterTeam();
            InitTriggerParameter();
            InitImageCaptureValue();
            InitControlRange(m_opCamList[m_indexCam]);
            InitBasicAdjustRange(m_opCamList[m_indexCam]);
            InitColorAdjustRange(m_opCamList[m_indexCam]);
            InitOtherRange(m_opCamList[m_indexCam]);

            UpdateInformation(m_opCamList[m_indexCam]);
            UpdateControlValue(m_opCamList[m_indexCam]);
            UpdateBasicAdjustmentValue(m_opCamList[m_indexCam]);
            UpdateColorAdjustmentValue(m_opCamList[m_indexCam]);
            UpdateOtherValue(m_opCamList[m_indexCam]);
            UpdateTriggerValue(m_opCamList[m_indexCam]);

            EnablePanelByWaitingState(false);

            splitContainer1.Panel1.VerticalScroll.Value = 0;
            splitContainer1.Panel1.VerticalScroll.Value = 0;
            this.PerformLayout();
            //          splitContainer1.Panel1.PerformLayout();
            //自动打开录制
            buttonLive_Click(null,null);
            //曝光时间
            numericUpDownMs.Value = 15;
            buttonExpOK_Click(null,null);
        }

        private void SamplePro_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (m_isWaiting)
            {
                StopWaitForFrame(m_opCamList[m_indexCam]);
            }
                        
            UnInitAllOpenedCamerasDrawing();
            CloseAllOpenedCameras();
            UnInitApi();
            if (settingCloseDelegate != null) {
                settingCloseDelegate.Invoke();
            }
        }

        private TUCAMRET InitApi()
        {
            /* Get the current directory */
            IntPtr strPath = Marshal.StringToHGlobalAnsi(System.Environment.CurrentDirectory);

            m_filePath = Marshal.PtrToStringAnsi(strPath) + "\\Image";

            m_itApi.uiCamCount = 0;
            m_itApi.pstrConfigPath = strPath;

            TUCamAPI.TUCAM_Api_Init(ref m_itApi);

            Console.WriteLine("Connect {0} camera", m_itApi.uiCamCount);

            if (0 == m_itApi.uiCamCount)
            {
                return TUCAMRET.TUCAMRET_NO_CAMERA;
            }

            return TUCAMRET.TUCAMRET_SUCCESS;
        }

        private TUCAMRET UnInitApi()
        {
            return TUCamAPI.TUCAM_Api_Uninit();
        }

        private TUCAMRET OpenAllConnectedCameras()
        {
            // Get the camera name
            TUCAM_VALUE_INFO valueInfo;
            valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_CAMERA_MODEL;
            valueInfo.nTextSize = 64;
            valueInfo.nValue = 0;
            valueInfo.pText = IntPtr.Zero;
            m_opCamList.Clear();
            comboBoxName.Items.Clear();

            for (uint i = 0; i < m_itApi.uiCamCount; ++i)
            {
                TUCAM_OPEN opCam;
                opCam.uiIdxOpen = i;
                opCam.hIdxTUCam = IntPtr.Zero;

                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Dev_Open(ref opCam))
                {
                    if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Dev_GetInfo(opCam.hIdxTUCam, ref valueInfo))
                    { 
                        comboBoxName.Items.Add(Marshal.PtrToStringAnsi(valueInfo.pText) /*+ " " + labelValueSn.Text*/);
                    }

                    m_opCamList.Add(opCam);
                }
            }

            if (m_opCamList.Count > 0)
            {
                return TUCAMRET.TUCAMRET_SUCCESS;
            }

            return TUCAMRET.TUCAMRET_FAILOPEN_CAMERA;
        }

        private TUCAMRET CloseAllOpenedCameras()
        {
            for (int i = 0; i < m_opCamList.Count; ++i)
            {
                TUCamAPI.TUCAM_Dev_Close(m_opCamList[i].hIdxTUCam);
            }

            m_opCamList.Clear();

            return TUCAMRET.TUCAMRET_SUCCESS;
        }

        private void InitAllOpenedCamerasDrawing()
        {
            TUCAM_OPEN opCam;
            TUCAM_VALUE_INFO valueInfo;
            TUCAM_DRAW_INIT itDraw;
            itDraw.hWnd = drawingBox.Handle;
            itDraw.nMode = 0;

            valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_CAMERA_CHANNELS;
            valueInfo.nValue = 1;
            valueInfo.nTextSize = 0;
            valueInfo.pText = IntPtr.Zero;

            m_itDrawList.Clear();

            for (int i = 0; i < m_opCamList.Count; ++i)
            {
                opCam = m_opCamList[i];

                valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_CAMERA_CHANNELS;
                TUCamAPI.TUCAM_Dev_GetInfo(opCam.hIdxTUCam, ref valueInfo);
                itDraw.ucChannels = (byte)valueInfo.nValue;

                valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_CURRENT_WIDTH;
                TUCamAPI.TUCAM_Dev_GetInfo(opCam.hIdxTUCam, ref valueInfo);
                itDraw.nWidth = valueInfo.nValue;

                valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_CURRENT_HEIGHT;
                TUCamAPI.TUCAM_Dev_GetInfo(opCam.hIdxTUCam, ref valueInfo);
                itDraw.nHeight = valueInfo.nValue;

                TUCamAPI.TUCAM_Draw_Init(opCam.hIdxTUCam, itDraw);

                m_itDrawList.Add(itDraw);
            }
        }

        private void UnInitAllOpenedCamerasDrawing()
        {
            for (int i = 0; i < m_opCamList.Count; ++i)
            {
                TUCamAPI.TUCAM_Draw_Uninit(m_opCamList[i].hIdxTUCam);
            }

            m_itDrawList.Clear();
        }

        private void InitAllTimers()
        {
            m_aeTimer = new System.Timers.Timer(1000);
            m_aeTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerAutoExposure);
            m_aeTimer.AutoReset = true;
            m_aeTimer.SynchronizingObject = this;

            m_onceAeTimer = new System.Timers.Timer(1000);
            m_onceAeTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerOnceAutoExposure);
            m_onceAeTimer.AutoReset = false; 
            m_onceAeTimer.SynchronizingObject = this;

            m_autoLeftLevelsTimer = new System.Timers.Timer(1000);
            m_autoLeftLevelsTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerAutoLeftLevels);
            m_autoLeftLevelsTimer.AutoReset = true;
            m_autoLeftLevelsTimer.SynchronizingObject = this;

            m_autoRightLevelsTimer = new System.Timers.Timer(1000);
            m_autoRightLevelsTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerAutoRightLevels);
            m_autoRightLevelsTimer.AutoReset = true;
            m_autoRightLevelsTimer.SynchronizingObject = this;

            m_awbTimer = new System.Timers.Timer(1000);
            m_awbTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerUpdateWhiteBalance);
            m_awbTimer.AutoReset = true;
            m_awbTimer.SynchronizingObject = this;

            m_onceWbTimer = new System.Timers.Timer(1000);
            m_onceWbTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerUpdateWhiteBalance);
            m_onceWbTimer.AutoReset = false;
            m_onceWbTimer.SynchronizingObject = this;
        }

        private void InitRoiParameter()
        {
            m_isRoi = false;
            textBoxHOffset.Text = "0";
            textBoxVOffset.Text = "0";
            textBoxWidth.Text = m_itDrawList[m_indexCam].nWidth.ToString();
            textBoxHeight.Text = m_itDrawList[m_indexCam].nHeight.ToString();

            UpdateRoiState(m_isRoi);
        }

        private void InitParameterTeam()
        {
            radioButtonParamA.Checked = true;
            radioButtonParamB.Checked = false;
            radioButtonParamC.Checked = false;
            radioButtonParamD.Checked = false;
        }

        private void InitTriggerParameter()
        {
            m_isTrigger = false;

            m_triggerAttr.nTgrMode = (int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE;
            m_triggerAttr.nFrames = 1;
            m_triggerAttr.nDelayTm = 0;
            m_triggerAttr.nExpMode = (int)TUCAM_TRIGGER_EXP.TUCTE_EXPTM;
            m_triggerAttr.nEdgeMode = (int)TUCAM_TRIGGER_EDGE.TUCTD_RISING;

            numericUpDownDelaySec.Minimum = 0;
            numericUpDownDelaySec.Maximum = 10;

            numericUpDownDelayMs.Minimum = 0;
            numericUpDownDelayMs.Maximum = 999;

            numericUpDownDelayUs.Minimum = 0;
            numericUpDownDelayUs.Maximum = 999;

            groupBoxTrigger.Enabled = false;
        }

        private void WaitForFrameThreadEntity()
        {
            int clientWinWidth = 0;
            int clientWinHeight = 0;

            int drawingWidth = 0;
            int drawingHeight = 0;
            int drawingOffsetX = 0;
            int drawingOffsetY = 0;

            UInt64 intervalTime = 0;
            IntPtr hIdxTUCam = m_opCamList[m_indexCam].hIdxTUCam;

            while (m_isWaiting)
            {
                // Calculate the frame speed
                m_drawingFramesCnt++;
                TimeSpan stopTime = new TimeSpan(DateTime.Now.Ticks);
                intervalTime = (UInt64)m_startTime.Subtract(stopTime).Duration().TotalMilliseconds;

                if (intervalTime > 1000)
                {
                    m_fps = m_drawingFramesCnt * 1000.0f / intervalTime;

                    UpdateFpsInvok updateFps = new UpdateFpsInvok(UpdateFps);
                    BeginInvoke(updateFps, new object[] { m_fps.ToString("#0.0 fps") });
  
                    m_startTime = stopTime;
                    m_drawingFramesCnt = 0;
                }

                m_frame.ucFormatGet = (byte)TUFRM_FORMATS.TUFRM_FMT_USUAl;
                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Buf_WaitForFrame(hIdxTUCam, ref m_frame))
                {
                    // Change drawing area
                    if (drawingBox.Width != m_frame.usWidth || drawingBox.Height != m_frame.usHeight || m_clientWinWidth != clientWinWidth || m_clientWinHeight != clientWinHeight)
                    {
                        clientWinWidth = drawingBox.Width;
                        clientWinHeight = drawingBox.Height;

                        float scaleX = clientWinWidth * 1.0f / m_frame.usWidth;
                        float scaleY = clientWinHeight * 1.0f / m_frame.usHeight;
                        float scale = scaleX > scaleY ? scaleY : scaleX;
                        scale = (float)((int)(scale * 100) / 100.0f);

                        if (scale < 1)
                        {
                            drawingWidth = (int)(scale * m_frame.usWidth);
                            drawingHeight = (int)(scale * m_frame.usHeight);
                        }
                        else
                        {
                            drawingWidth = m_frame.usWidth;
                            drawingHeight = m_frame.usHeight;
                        }

                        drawingWidth = (drawingWidth >> 2) << 2;
                        drawingHeight = (drawingHeight >> 2) << 2;

                        drawingOffsetX = (clientWinWidth - drawingWidth) / 2;
                        drawingOffsetY = (clientWinHeight - drawingHeight) / 2;
                    }

                    // Drawing image
                    if (IntPtr.Zero != m_frame.pBuffer)
                    {
                        m_drawing.pFrame = Marshal.AllocHGlobal(Marshal.SizeOf(m_frame));
                        Marshal.StructureToPtr(m_frame, m_drawing.pFrame, true);

                        m_drawing.nDstX = drawingOffsetX;
                        m_drawing.nDstY = drawingOffsetY;
                        m_drawing.nDstWidth = drawingWidth;
                        m_drawing.nDstHeight = drawingHeight;

                        m_drawing.nSrcX = 0;
                        m_drawing.nSrcY = 0;
                        m_drawing.nSrcWidth = m_frame.usWidth;
                        m_drawing.nSrcHeight = m_frame.usHeight;

                        TUCamAPI.TUCAM_Draw_Frame(hIdxTUCam, ref m_drawing);
                    }

                    // Saving video
                    if (m_isRecording)
                    {
                        TUCamAPI.TUCAM_Rec_AppendFrame(hIdxTUCam, ref m_frame);
                    }

                    // Saving image
                    if (m_isSaving || m_isTrigger)
                    {                      
                        string fileName = m_filePath + "\\" + m_imageName + "_" + m_captureTimes + "_" + m_savedFramesCnt++;

                        bool isSucceed = false;

                        do
                        {
                            int fileFormat = m_savedFormat;
                            TUCAM_FILE_SAVE fileSave;

                            fileSave.pstrSavePath = Marshal.StringToHGlobalAnsi(fileName); 

                            // struct to IntPtr
                            fileSave.pFrame = Marshal.AllocHGlobal(Marshal.SizeOf(m_frame));
                            Marshal.StructureToPtr(m_frame, fileSave.pFrame, true);
                            
                            // Format RAW
                            if (0 != (fileFormat & (int)TUIMG_FORMATS.TUFMT_RAW))
                            {
                                fileFormat &= ~(int)TUIMG_FORMATS.TUFMT_RAW;
                            }

                            if (0 != fileFormat)
                            {
                                fileSave.nSaveFmt = fileFormat;

                                // Save other format data(TIFF/BMP/PNG/JPEG)
                                if (TUCAMRET.TUCAMRET_SUCCESS != TUCamAPI.TUCAM_File_SaveImage(hIdxTUCam, fileSave))
                                {
                                    break;
                                }
                            }

                            if (0 != (m_savedFormat & (int)TUIMG_FORMATS.TUFMT_RAW))
						    {
							    fileSave.nSaveFmt = (int)TUIMG_FORMATS.TUFMT_RAW;

							    // Get RAW data
							    m_frame.ucFormatGet = (int)TUFRM_FORMATS.TUFRM_FMT_RAW;
							    if (TUCAMRET.TUCAMRET_SUCCESS != TUCamAPI.TUCAM_Buf_CopyFrame(hIdxTUCam, ref m_frame))
							    {
								    break;
							    }

							    // Save RAW data
                                if (TUCAMRET.TUCAMRET_SUCCESS != TUCamAPI.TUCAM_File_SaveImage(hIdxTUCam, fileSave))
							    {
								    break;
							    }
						    }
                            /*BaiDuOcr baiDuOcr = new BaiDuOcr();
                            BaiduReturn.Text=baiDuOcr.GeneralBasicDemo(fileName+".jpg");
                            Client client=AlibabaOCR.CreateClient();
                            Stream bodySyream = AlibabaCloud.DarabonbaStream.StreamUtil.ReadFromFilePath(fileName + ".jpg");
                            AlibabaCloud.SDK.Ocr_api20210707.Models.RecognizeAdvancedRequest recognizeAdvancedRequest = new AlibabaCloud.SDK.Ocr_api20210707.Models.RecognizeAdvancedRequest
                            {
                                Body = bodySyream,
                                OutputFigure = true,
                                Row = true,
                                NeedSortPage = true,
                                NeedRotate = true,
                                OutputCharInfo = true,
                            };
                            AlibabaCloud.SDK.Ocr_api20210707.Models.RecognizeAdvancedResponse resp = client.RecognizeAdvanced(recognizeAdvancedRequest);
                            JObject jo = JObject.Parse(AlibabaCloud.TeaUtil.Common.ToJSONString(resp));
                            JObject dataJo=  JObject.Parse(jo.GetValue("Body")["Data"].ToString());
                            AlibabaCloud.TeaConsole.Client.Log(jo.GetValue("Body")["Data"].ToString());
                            //aireturn.Text = AlibabaCloud.TeaUtil.Common.ToJSONString(dataJo.GetValue("content"));
                            aireturn.Text = dataJo.GetValue("content").ToString();
                            AlibabaCloud.TeaConsole.Client.Log(AlibabaCloud.TeaUtil.Common.ToJSONString(resp));
                            TencentOCR tencentOCR = new TencentOCR();
                            TencentReturn.Text=tencentOCR.GetTencentOCR(fileName + ".jpg");*/
                            isSucceed = true;

                        } while (false);

                        if (isSucceed)
                        {
                            m_savedSucceedCnt++;

                            // capture finished
                            if (m_savedSucceedCnt >= m_totalFrames)
                            {
                                m_isSaving = false;

                                FinishedCaptureInvok finished = new FinishedCaptureInvok(FinishedCapture);
                                BeginInvoke(finished, new object[] { m_savedSucceedCnt });    
                            }
                        }
                    }
                }
            }
        }

        private void StartWaitForFrame(TUCAM_OPEN opCam)
        {
            if (m_isWaiting)
                return;

            if (m_opCamList.Count > 0)
            {
                m_isWaiting = true;
                m_waitingThread = new Thread(new ThreadStart(WaitForFrameThreadEntity));

                m_frame.pBuffer = IntPtr.Zero;
                m_frame.ucFormatGet = (byte)TUFRM_FORMATS.TUFRM_FMT_USUAl;
                m_frame.uiRsdSize = 1;

                TUCamAPI.TUCAM_Buf_Alloc(opCam.hIdxTUCam, ref m_frame);                           // Alloc buffer after set resolution or set ROI attribute                                           
                TUCamAPI.TUCAM_Cap_Start(opCam.hIdxTUCam, (uint)m_triggerAttr.nTgrMode);          // Start capture

                m_waitingThread.Start();
            }
        }

        private void StopWaitForFrame(TUCAM_OPEN opCam)
        {
            if (!m_isWaiting)
                return;

            if (m_opCamList.Count > 0)
            {
                m_isSaving = false;
                m_isWaiting = false;
                m_drawingFramesCnt = 0;
                m_startTime = new TimeSpan(DateTime.Now.Ticks);

                TUCamAPI.TUCAM_Buf_AbortWait(opCam.hIdxTUCam);
                m_waitingThread.Join();
                m_waitingThread.Abort();

                TUCamAPI.TUCAM_Cap_Stop(opCam.hIdxTUCam);                  // Stop capture   
                TUCamAPI.TUCAM_Buf_Release(opCam.hIdxTUCam);               // Release alloc buffer after stop capture and quit drawing thread
            }
        }

        private void EnablePanelByWaitingState(bool isWaiting)
        {
            comboBoxRes.Enabled = !isWaiting;
            comboBoxName.Enabled = !isWaiting;

            radioButton1x1.Enabled = isWaiting ? false : m_isSupportBinng;
            radioButton2x2.Enabled = isWaiting ? false : m_isSupportBinng;
            radioButton3x3.Enabled = isWaiting ? false : m_isSupportBinng;
            radioButton4x4.Enabled = isWaiting ? false : m_isSupportBinng;

            buttonRecord.Enabled = isWaiting;
            buttonCapture.Enabled = isWaiting;
        }

        private void UpdateInformation(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            // Get the camera SN
            string snStr = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
            TUCAM_REG_RW regRW;
            regRW.nBufSize = 64;
            regRW.pBuf = Marshal.StringToHGlobalAnsi(snStr);
            regRW.nRegType = (int)TUREG_TYPE.TUREG_SN;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Reg_Read(opCam.hIdxTUCam, regRW))
            {
                string str = Marshal.PtrToStringAnsi(regRW.pBuf);
                labelValueSn.Text = str;
            }
            else
            {
                labelValueSn.Text = "";
            }

            // Get the camera name
            TUCAM_VALUE_INFO valueInfo;
            valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_CAMERA_MODEL;
            valueInfo.nTextSize = 64;
            valueInfo.nValue = 0;
            valueInfo.pText = IntPtr.Zero;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Dev_GetInfo(opCam.hIdxTUCam, ref valueInfo))
            {
                comboBoxName.Text = Marshal.PtrToStringAnsi(valueInfo.pText) /*+ " " + labelValueSn.Text*/;
            }

            // Get firmware version
            valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_VERSION_FRMW;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Dev_GetInfo(opCam.hIdxTUCam, ref valueInfo))
            {
                if (valueInfo.nValue == 0)
                {
                    int nLength = valueInfo.nTextSize / 2;
                    string fwString;
                    string fpgaString;
                    string textString;
                    textString = Marshal.PtrToStringAnsi(valueInfo.pText);
                    fpgaString = textString.Substring(0, nLength);
                    fwString = textString.Substring(nLength, nLength);

                    labelValueFw.Text = fwString;
                    labelValueFpga.Text = fpgaString;
                }
                else
                {
                    string camvertion = valueInfo.nValue.ToString();
                    labelValueFw.Text = System.Convert.ToString(int.Parse(camvertion), 16);
                }

            }

            // Get USB Type
            valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_BUS;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Dev_GetInfo(opCam.hIdxTUCam, ref valueInfo))
            {
                if (0x200 == valueInfo.nValue || 0x210 == valueInfo.nValue)
                {
                    labelValueUsb.Text = "2.0";
                }
                else
                {
                    labelValueUsb.Text = "3.0";
                }
            }

            // Get SDK version
            valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_VERSION_API;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Dev_GetInfo(opCam.hIdxTUCam, ref valueInfo))
            {
                labelValueSdk.Text = Marshal.PtrToStringAnsi(valueInfo.pText);
            }

            // Get camera PID
            valueInfo.nID = (int)TUCAM_IDINFO.TUIDI_PRODUCT;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Dev_GetInfo(opCam.hIdxTUCam, ref valueInfo))
            {
                m_pid = valueInfo.nValue;
            }
        }

        private void InitControlRange(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            //图像水平翻转
            TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_HORIZONTAL, 1);
            //图像垂直翻转
            TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_VERTICAL, 1);

            TUCAM_VALUE_TEXT valueText;
            valueText.nTextSize = 64;
            string textStr = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
            valueText.pText = Marshal.StringToHGlobalAnsi(textStr);

            // Get resolution range
            m_resolutionCapa.nValDft = 0;
            m_resolutionCapa.nValMin = 0;
            m_resolutionCapa.nValMax = 0;
            m_resolutionCapa.nValStep = 0;
            m_resolutionCapa.idCapa = (int)TUCAM_IDCAPA.TUIDC_RESOLUTION;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetAttr(opCam.hIdxTUCam, ref m_resolutionCapa))
            {
                comboBoxRes.Items.Clear();
                int nCnt = m_resolutionCapa.nValMax - m_resolutionCapa.nValMin + 1;

                valueText.nID = (int)TUCAM_IDCAPA.TUIDC_RESOLUTION;
                for (int i = 0; i < nCnt; ++i)
                {
                    valueText.dbValue = i;
                    TUCamAPI.TUCAM_Capa_GetValueText(opCam.hIdxTUCam, ref valueText);
                    comboBoxRes.Items.Add(Marshal.PtrToStringAnsi(valueText.pText));
                }
            }

            // Get binning range
            m_binningCapa.nValDft = 0;
            m_binningCapa.nValDft = 0;
            m_binningCapa.nValMin = 0;
            m_binningCapa.nValMax = 0;
            m_binningCapa.nValStep = 0;
            m_binningCapa.idCapa = (int)TUCAM_IDCAPA .TUIDC_BINNING_SUM;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetAttr(opCam.hIdxTUCam, ref m_binningCapa))
            {
                m_isSupportBinng = true;

                radioButton1x1.Enabled = true;
                radioButton2x2.Enabled = true;
                radioButton3x3.Enabled = true;
                radioButton4x4.Enabled = true;
            }
            else
            {
                m_isSupportBinng = false;

                radioButton1x1.Enabled = false;
                radioButton2x2.Enabled = false;
                radioButton3x3.Enabled = false;
                radioButton4x4.Enabled = false;
            }

            // Get gain range
            m_gainProp.dbValDft = 0;
            m_gainProp.dbValMin = 0;
            m_gainProp.dbValMax = 0;
            m_gainProp.dbValStep = 0;
            m_gainProp.idProp = (int)TUCAM_IDPROP.TUIDP_GLOBALGAIN;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_gainProp))
            {
                if ((int)m_gainProp.dbValMax > 5)
                {
                    trackBarGain.Show();

                    trackBarGain.SetRange((int)m_gainProp.dbValMin, (int)m_gainProp.dbValMax);
                }
                else
                {
                    trackBarGain.Hide();
                }
            }

            // Get auto exposure 
            m_aeCapa.nValDft = 0;
            m_aeCapa.nValMin = 0;
            m_aeCapa.nValMax = 0;
            m_aeCapa.nValStep = 0;
		    m_aeCapa.idCapa = (int)TUCAM_IDCAPA.TUIDC_ATEXPOSURE;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetAttr(opCam.hIdxTUCam, ref m_aeCapa))
		    {
                if (m_aeCapa.nValMax > 1)
                {
                    buttonOnceAe.Show();
                    checkBoxAE.Hide();
                }
                else
                {
                    buttonOnceAe.Hide();
                    checkBoxAE.Show();
                    checkBoxAE.Enabled = true;
                }
            }
            else
            {
                buttonOnceAe.Hide();
                checkBoxAE.Show();
                checkBoxAE.Enabled = false;
            }          

            // Get auto exposure time target range
            m_aeTargetProp.dbValDft = 0;
            m_aeTargetProp.dbValMin = 0;
            m_aeTargetProp.dbValMax = 0;
            m_aeTargetProp.dbValStep = 0;
            m_aeTargetProp.idProp = (int)TUCAM_IDPROP.TUIDP_BRIGHTNESS;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_aeTargetProp))
            {
                trackBarTarget.Enabled = true;
                labelNameTarget.Enabled = true;
                labelValueTarget.Enabled = true;

                m_isSupportAeTarget = true;
                trackBarTarget.SetRange((int)m_aeTargetProp.dbValMin, (int)m_aeTargetProp.dbValMax);

                // MIchrome camera series must set TUIDC_ATEXPOSURE_MODE to use auto exposure time target 
                TUCamAPI.TUCAM_Capa_SetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATEXPOSURE_MODE, 3);
            }
            else
            {
                trackBarTarget.Enabled = false;
                labelNameTarget.Enabled = false;
                labelValueTarget.Enabled = false;

                m_isSupportAeTarget = false;
            }

            // Get exposure time range
            m_isSupportMs = true;
            m_isSupportSec = true;

            m_exposureProp.dbValDft = 0;
            m_exposureProp.dbValMin = 0;
            m_exposureProp.dbValMax = 0;
            m_exposureProp.dbValStep = 0;
            m_exposureProp.idProp = (int)TUCAM_IDPROP.TUIDP_EXPOSURETM;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_exposureProp))
            {
                labelNameSec.Enabled = true;
                labelNameMs.Enabled = true;
                labelNameUs.Enabled = true;
                
                numericUpDownSec.Enabled = true;
                numericUpDownMs.Enabled = true;
                numericUpDownUs.Enabled = true;

                if (PID_MICHROME5PRO == m_pid || PID_MICHROME6 == m_pid)
                {
                    m_exposureProp.dbValMin = 0.13;
                    m_exposureProp.dbValMax = 15000000;
                }

                uint expStep = (uint)(m_exposureProp.dbValStep * 1000 + 0.5f);

                if ((UInt64)(m_exposureProp.dbValMax * 1000) < 1000000)
                {
                    m_isSupportSec = false;

                    labelNameSec.Enabled = false;
                    numericUpDownSec.Enabled = false;
                }

                if ((UInt64)(m_exposureProp.dbValMax * 1000) < 1000)
                {
                    m_isSupportMs = false;
                    m_isSupportSec = false;

                    labelNameSec.Enabled = false;
                    labelNameMs.Enabled = false;

                    numericUpDownSec.Enabled = false;
                    numericUpDownMs.Enabled = false;
                }

                numericUpDownSec.Minimum = 0;
                numericUpDownSec.Maximum = (uint)(m_exposureProp.dbValMax / 1000);

                numericUpDownMs.Minimum = 0;
                numericUpDownMs.Maximum = 999;

                numericUpDownUs.Minimum = 0;
                numericUpDownUs.Maximum = 999;
            }
        }

        private void InitBasicAdjustRange(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            // Get auto levels
            m_autoLevelsCapa.nValDft = 0;
            m_autoLevelsCapa.nValMin = 0;
            m_autoLevelsCapa.nValMax = 0;
            m_autoLevelsCapa.nValStep = 0;
            m_autoLevelsCapa.idCapa = (int)TUCAM_IDCAPA.TUIDC_ATLEVELS;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetAttr(opCam.hIdxTUCam, ref m_autoLevelsCapa))
            {
                labelAutoLevel.Enabled = true;
                checkBoxLeftLevel.Enabled = true;
                checkBoxRightLevel.Enabled = true;
            }
            else
            {
                labelAutoLevel.Enabled = false;
                checkBoxLeftLevel.Enabled = false;
                checkBoxRightLevel.Enabled = false;

            }

            // Get left level range
            m_leftLevelProp.dbValDft = 0;
            m_leftLevelProp.dbValMin = 0;
            m_leftLevelProp.dbValMax = 0;
            m_leftLevelProp.dbValStep = 0;
            m_leftLevelProp.idProp = (int)TUCAM_IDPROP.TUIDP_LFTLEVELS;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_leftLevelProp))
            {
                trackBarLeftLevel.Enabled = true;
                labelNameLeftLevel.Enabled = true;
                labelValueLeftLevel.Enabled = true;

                trackBarLeftLevel.SetRange((int)m_leftLevelProp.dbValMin, (int)m_leftLevelProp.dbValMax);
            }
            else
            {
                trackBarLeftLevel.Enabled = false;
                labelNameLeftLevel.Enabled = false;
                labelValueLeftLevel.Enabled = false;
            }

            // Get right level range
            m_rightLevelProp.dbValDft = 0;
            m_rightLevelProp.dbValMin = 0;
            m_rightLevelProp.dbValMax = 0;
            m_rightLevelProp.dbValStep = 0;
            m_rightLevelProp.idProp = (int)TUCAM_IDPROP.TUIDP_RGTLEVELS;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_rightLevelProp))
            {
                trackBarRightLevel.Enabled = true;
                labelNameRightLevel.Enabled = true;
                labelValueRightLevel.Enabled = true;

                trackBarRightLevel.SetRange((int)m_rightLevelProp.dbValMin, (int)m_rightLevelProp.dbValMax);
            }
            else
            {
                trackBarRightLevel.Enabled = false;
                labelNameRightLevel.Enabled = false;
                labelValueRightLevel.Enabled = false;
            }

            // Get gamma range
            m_gammaProp.dbValDft = 0;
            m_gammaProp.dbValMin = 0;
            m_gammaProp.dbValMax = 0;
            m_gammaProp.dbValStep = 0;
            m_gammaProp.idProp = (int)TUCAM_IDPROP.TUIDP_GAMMA;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_gammaProp))
            {
                trackBarGamma.Enabled = true;
                labelNameGamma.Enabled = true;
                labelValueGamma.Enabled = true;

                trackBarGamma.SetRange((int)m_gammaProp.dbValMin, (int)m_gammaProp.dbValMax);
            }
            else
            {
                trackBarGamma.Enabled = false;
                labelNameGamma.Enabled = false;
                labelValueGamma.Enabled = false;
            }


            // Get contrast range
            m_contrastProp.dbValDft = 0;
            m_contrastProp.dbValMin = 0;
            m_contrastProp.dbValMax = 0;
            m_contrastProp.dbValStep = 0;
            m_contrastProp.idProp = (int)TUCAM_IDPROP.TUIDP_CONTRAST;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_contrastProp))
            {
                trackBarContrast.Enabled = true;
                labelNameContrast.Enabled = true;
                labelValueContrast.Enabled = true;

                trackBarContrast.SetRange((int)m_contrastProp.dbValMin, (int)m_contrastProp.dbValMax);
            }
            else
            {
                trackBarContrast.Enabled = false;
                labelNameContrast.Enabled = false;
                labelValueContrast.Enabled = false;
            }

            // Get sharpness range
            m_sharpnessProp.dbValDft = 0;
            m_sharpnessProp.dbValMin = 0;
            m_sharpnessProp.dbValMax = 0;
            m_sharpnessProp.dbValStep = 0;
            m_sharpnessProp.idProp = (int)TUCAM_IDPROP.TUIDP_SHARPNESS;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_sharpnessProp))
            {
                trackBarSharpness.Enabled = true;
                labelNameSharpness.Enabled = true;
                labelValueSharpness.Enabled = true;

                trackBarSharpness.SetRange((int)m_sharpnessProp.dbValMin, (int)m_sharpnessProp.dbValMax);
            }
            else
            {
                trackBarSharpness.Enabled = false;
                labelNameSharpness.Enabled = false;
                labelValueSharpness.Enabled = false;
            }

            // Get permeability range
            m_permeabilityProp.dbValDft = 0;
            m_permeabilityProp.dbValMin = 0;
            m_permeabilityProp.dbValMax = 0;
            m_permeabilityProp.dbValStep = 0;
            m_permeabilityProp.idProp = (int)TUCAM_IDPROP.TUIDP_ENHANCE_STRENGTH;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_permeabilityProp))
            {
                trackBarPermeability.Enabled = true;
                labelNamePermeability.Enabled = true;
                labelValuePermeability.Enabled = true;

                trackBarPermeability.SetRange((int)m_permeabilityProp.dbValMin, (int)m_permeabilityProp.dbValMax);
            }
            else
            {
                trackBarPermeability.Enabled = false;
                labelNamePermeability.Enabled = false;
                labelValuePermeability.Enabled = false;
            }
        }

        private void InitColorAdjustRange(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            // 获取单色模式
            m_monochromeCapa.nValDft = 0;
            m_monochromeCapa.nValMin = 0;
            m_monochromeCapa.nValMax = 0;
            m_monochromeCapa.nValStep = 0;
            m_monochromeCapa.idCapa = (int)TUCAM_IDCAPA.TUIDC_MONOCHROME;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetAttr(opCam.hIdxTUCam, ref m_monochromeCapa))
            {
                checkBoxGray.Enabled = true;
            }
            else
            {
                checkBoxGray.Enabled = false; 
            }

            // 获取自动白平衡
            m_awbCapa.nValDft = 0;
            m_awbCapa.nValMin = 0;
            m_awbCapa.nValMax = 0;
            m_awbCapa.nValStep = 0;
            m_awbCapa.idCapa = (int)TUCAM_IDCAPA.TUIDC_ATWBALANCE;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetAttr(opCam.hIdxTUCam, ref m_awbCapa))
            {
                if (m_awbCapa.nValMax > 1)
                {
                    checkBoxAWB.Enabled = true;
                    checkBoxAWB.Show();
                    buttonOnceWB.Hide();
                }
                else
                {
                    buttonOnceWB.Enabled = true;
                    checkBoxAWB.Hide();
                    buttonOnceWB.Show();
                }
            }
            else
            {
                checkBoxAWB.Enabled = false;
                checkBoxAWB.Show();
                buttonOnceWB.Hide();
            }

            // Get red channel range
            m_redChannelProp.nIdxChn = 1;
            m_redChannelProp.dbValDft = 0;
            m_redChannelProp.dbValMin = 0;
            m_redChannelProp.dbValMax = 0;
            m_redChannelProp.dbValStep = 0;
            m_redChannelProp.idProp = (int)TUCAM_IDPROP.TUIDP_CHNLGAIN;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_redChannelProp))
            {
                trackBarRed.Enabled = true;
                labelNameRed.Enabled = true;
                labelValueRed.Enabled = true;

                trackBarRed.SetRange((int)m_redChannelProp.dbValMin, (int)m_redChannelProp.dbValMax);
            }
            else
            {
                trackBarRed.Enabled = false;
                labelNameRed.Enabled = false;
                labelValueRed.Enabled = false;
            }

            // Get green channel range
            m_greenChannelProp.nIdxChn = 2;
            m_greenChannelProp.dbValDft = 0;
            m_greenChannelProp.dbValMin = 0;
            m_greenChannelProp.dbValMax = 0;
            m_greenChannelProp.dbValStep = 0;
            m_greenChannelProp.idProp = (int)TUCAM_IDPROP.TUIDP_CHNLGAIN;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_greenChannelProp))
            {
                trackBarGreen.Enabled = true;
                labelNameGreen.Enabled = true;
                labelValueGreen.Enabled = true;

                trackBarGreen.SetRange((int)m_greenChannelProp.dbValMin, (int)m_greenChannelProp.dbValMax);
            }
            else
            {
                trackBarGreen.Enabled = false;
                labelNameGreen.Enabled = false;
                labelValueGreen.Enabled = false;
            }

            // Get blue channel range
            m_blueChannelProp.nIdxChn = 3;
            m_blueChannelProp.dbValDft = 0;
            m_blueChannelProp.dbValMin = 0;
            m_blueChannelProp.dbValMax = 0;
            m_blueChannelProp.dbValStep = 0;
            m_blueChannelProp.idProp = (int)TUCAM_IDPROP.TUIDP_CHNLGAIN;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_blueChannelProp))
            {
                trackBarBlue.Enabled = true;
                labelNameBlue.Enabled = true;
                labelValueBlue.Enabled = true;

                trackBarBlue.SetRange((int)m_blueChannelProp.dbValMin, (int)m_blueChannelProp.dbValMax);
            }
            else
            {
                trackBarBlue.Enabled = false;
                labelNameBlue.Enabled = false;
                labelValueBlue.Enabled = false;
            }

            // Get color temperature range
            m_cctProp.nIdxChn = 0;
            m_cctProp.dbValDft = 0;
            m_cctProp.dbValMin = 0;
            m_cctProp.dbValMax = 0;
            m_cctProp.dbValStep = 0;
            m_cctProp.idProp = (int)TUCAM_IDPROP.TUIDP_CLRTEMPERATURE;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_cctProp))
            {
                m_isSupportCCT = true;

                trackBarColorTemperature.Enabled = true;
                labelNameColorTemperature.Enabled = true;
                labelValueColorTemperature.Enabled = true;

                trackBarColorTemperature.SetRange((int)m_cctProp.dbValMin, (int)m_cctProp.dbValMax);
            }
            else
            {
                m_isSupportCCT = false;

                trackBarColorTemperature.Enabled = false;
                labelNameColorTemperature.Enabled = false;
                labelValueColorTemperature.Enabled = false;
            }

            // Get saturation range
            m_saturationProp.nIdxChn = 0;
            m_saturationProp.dbValDft = 0;
            m_saturationProp.dbValMin = 0;
            m_saturationProp.dbValMax = 0;
            m_saturationProp.dbValStep = 0;
            m_saturationProp.idProp = (int)TUCAM_IDPROP.TUIDP_SATURATION;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_saturationProp))
            {
                trackBarSaturation.Enabled = true;
                labelNameSaturation.Enabled = true;
                labelValueSaturation.Enabled = true;

                trackBarSaturation.SetRange((int)m_saturationProp.dbValMin, (int)m_saturationProp.dbValMax);
            }
            else
            {
                trackBarSaturation.Enabled = false;
                labelNameSaturation.Enabled = false;
                labelValueSaturation.Enabled = false;
            }

            // Get hue range
            m_hueProp.nIdxChn = 0;
            m_hueProp.dbValDft = 0;
            m_hueProp.dbValMin = 0;
            m_hueProp.dbValMax = 0;
            m_hueProp.dbValStep = 0;
            m_hueProp.idProp = (int)TUCAM_IDPROP.TUIDP_HUE;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_hueProp))
            {
                trackBarHue.Enabled = true;
                labelNameHue.Enabled = true;
                labelValueHue.Enabled = true;

                trackBarHue.SetRange((int)m_hueProp.dbValMin, (int)m_hueProp.dbValMax);
            }
            else
            {
                trackBarHue.Enabled = false;
                labelNameHue.Enabled = false;
                labelValueHue.Enabled = false;
            }

            // Get light range
            m_lightProp.nIdxChn = 0;
            m_lightProp.dbValDft = 0;
            m_lightProp.dbValMin = 0;
            m_lightProp.dbValMax = 0;
            m_lightProp.dbValStep = 0;
            m_lightProp.idProp = (int)TUCAM_IDPROP.TUIDP_LIGHT;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetAttr(opCam.hIdxTUCam, ref m_lightProp))
            {
                trackBarLight.Enabled = true;
                labelNameLight.Enabled = true;
                labelValueLight.Enabled = true;

                trackBarLight.SetRange((int)m_lightProp.dbValMin, (int)m_lightProp.dbValMax);
            }
            else
            {
                trackBarLight.Enabled = false;
                labelNameLight.Enabled = false;
                labelValueLight.Enabled = false;
            }
        }

        private void InitOtherRange(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            // Get HDR 
            m_hdrCapa.nValDft = 0;
            m_hdrCapa.nValMin = 0;
            m_hdrCapa.nValMax = 0;
            m_hdrCapa.nValStep = 0;
            m_hdrCapa.idCapa = (int)TUCAM_IDCAPA.TUIDC_HDR;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetAttr(opCam.hIdxTUCam, ref m_hdrCapa))
            {
                checkBoxHdr.Enabled = true;
            }
            else
            {
                checkBoxHdr.Enabled = false;
            }

            // Get horizontal 
            m_horizontalCapa.nValDft = 0;
            m_horizontalCapa.nValMin = 0;
            m_horizontalCapa.nValMax = 0;
            m_horizontalCapa.nValStep = 0;
            m_horizontalCapa.idCapa = (int)TUCAM_IDCAPA.TUIDC_HORIZONTAL;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetAttr(opCam.hIdxTUCam, ref m_horizontalCapa))
            {
                checkBoxHorizontal.Enabled = true;
            }
            else
            {
                checkBoxHorizontal.Enabled = false;
            }

            // Get vertical
            m_verticalCapa.nValDft = 0;
            m_verticalCapa.nValMin = 0;
            m_verticalCapa.nValMax = 0;
            m_verticalCapa.nValStep = 0;
            m_verticalCapa.idCapa = (int)TUCAM_IDCAPA.TUIDC_VERTICAL;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetAttr(opCam.hIdxTUCam, ref m_verticalCapa))
            {
                checkBoxVertical.Enabled = true;
            }
            else
            {
                checkBoxVertical.Enabled = false;
            }
        }

        private void InitImageCaptureValue()
        {
            int totalFrames = 1;

            textBoxPath.Text = m_filePath;
            textBoxImageName.Text = "TS";
            textBoxTotalFrames.Text = totalFrames.ToString();

            checkBoxTiff.Checked = true;
            checkBoxRaw.Checked = false;
            checkBoxJpg.Checked = false;
            checkBoxPng.Checked = false;
            checkBoxBmp.Checked = false;

            m_savedFormatCnt = 1;
            m_savedFormat = (int)(TUIMG_FORMATS.TUFMT_TIF);

            m_captureTimes = 0;
            m_savedFramesCnt = 1;
            m_savedSucceedCnt = 0; 
        }

        private void UpdateExposureTime(UInt64 exposureTime)
        {
            if (PID_MICHROME5PRO == m_pid || PID_MICHROME6 == m_pid)
            {
                if (exposureTime < 137)
                    exposureTime = 130;

                if (exposureTime > 15000000)
                    exposureTime = 15000000;
            }

            uint secValue = (uint)(exposureTime / (1000 * 1000));
            uint msValue = (uint)(exposureTime / 1000) % 1000;
            uint usValue = (uint)exposureTime % 1000;

            numericUpDownSec.Value = secValue;
            numericUpDownMs.Value = msValue;
            numericUpDownUs.Value = usValue;
        }

        private void UpdateDelayTime(UInt64 delayTime)
        {
            if (delayTime > 10000000)
                delayTime = 10000000;

            uint secValue = (uint)(delayTime / (1000 * 1000));
            uint msValue = (uint)(delayTime / 1000) % 1000;
            uint usValue = (uint)delayTime % 1000;

            numericUpDownDelaySec.Value = secValue;
            numericUpDownDelayMs.Value = msValue;
            numericUpDownDelayUs.Value = usValue;
        }

        private void UpdateATExposureState(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            int aeState = 0;
            double gainValue = 0;
            double aeTargetValue = 0;
            double exposureValue = 0;

            bool isAeState = false;

            // Get the current auto exposure time state
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATEXPOSURE, ref aeState))
            {
                isAeState = (1 == aeState) ? true : false;

                if (isAeState)
                {
                    checkBoxAE.Checked = true;
                    buttonExpOK.Enabled = false;

                    labelNameSec.Enabled = false;
                    labelNameMs.Enabled = false;
                    labelNameUs.Enabled = false;

                    numericUpDownSec.Enabled = false;
                    numericUpDownMs.Enabled = false;
                    numericUpDownUs.Enabled = false;

                    m_aeTimer.Start();
                }
                else
                {
                    checkBoxAE.Checked = false;
                    buttonExpOK.Enabled = true;

                    labelNameSec.Enabled = m_isSupportSec;
                    labelNameMs.Enabled = m_isSupportMs;
                    labelNameUs.Enabled = true;

                    numericUpDownSec.Enabled = m_isSupportSec;
                    numericUpDownMs.Enabled = m_isSupportMs;
                    numericUpDownUs.Enabled = true;

                    m_aeTimer.Stop();
                }
            }

            // Get the current gain value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_GLOBALGAIN, ref gainValue, 0))
            {
                trackBarGain.Value = (int)gainValue;
                labelValueGain.Text = gainValue.ToString();

                trackBarGain.Enabled = !isAeState;
                labelNameGain.Enabled = !isAeState;
                labelValueGain.Enabled = !isAeState;
            }
            else
            {
                trackBarGain.Enabled = false;
                labelNameGain.Enabled = false;
                labelValueGain.Enabled = false;
            }

            // Get the current target value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_BRIGHTNESS, ref aeTargetValue, 0))
            {
                trackBarTarget.Value = (int)aeTargetValue;
                labelValueTarget.Text = aeTargetValue.ToString();

                trackBarTarget.Enabled = m_isSupportAeTarget && isAeState;
                labelNameTarget.Enabled = m_isSupportAeTarget && isAeState;
                labelValueTarget.Enabled = m_isSupportAeTarget && isAeState;
            }
            else
            {
                trackBarTarget.Enabled = false;
                labelNameTarget.Enabled = false;
                labelValueTarget.Enabled = false;
            }


            // Get the current exposure time value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_EXPOSURETM, ref exposureValue, 0))
            {
                UpdateExposureTime((UInt64)(exposureValue * 1000));
            }
        }

        private void UpdateATLevelsState(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            double paramValue = 0;
            int autoLevelsState = 0;

            // Get current auto levels status
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATLEVELS, ref autoLevelsState))
            {
                // Auto left levels 
                if (0 != (autoLevelsState & 0x01))
                {
                    m_autoLeftLevelsTimer.Start();
                    checkBoxLeftLevel.Checked = true;

                    trackBarLeftLevel.Enabled = false;
                    labelNameLeftLevel.Enabled = false;
                    labelValueLeftLevel.Enabled = false;
                }
                else
                {
                    m_autoLeftLevelsTimer.Stop();
                    checkBoxLeftLevel.Checked = false;

                    trackBarLeftLevel.Enabled = true;
                    labelNameLeftLevel.Enabled = true;
                    labelValueLeftLevel.Enabled = true;
                }

                // Auto right levels
                if (0 != (autoLevelsState & 0x02))
                {
                    m_autoRightLevelsTimer.Start();
                    checkBoxRightLevel.Checked = true;

                    trackBarRightLevel.Enabled = false;
                    labelNameRightLevel.Enabled = false;
                    labelValueRightLevel.Enabled = false;
                }
                else
                {
                    m_autoRightLevelsTimer.Stop();
                    checkBoxRightLevel.Checked = false;

                    trackBarRightLevel.Enabled = true;
                    labelNameRightLevel.Enabled = true;
                    labelValueRightLevel.Enabled = true;
                }
            }

            // Get current left levels
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_LFTLEVELS, ref paramValue, 0))
            {
                trackBarLeftLevel.Value = (int)paramValue;
                labelValueLeftLevel.Text = trackBarLeftLevel.Value.ToString();
            }

            // Get current right levels
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_RGTLEVELS, ref paramValue, 0))
            {
                trackBarRightLevel.Value = (int)paramValue;
                labelValueRightLevel.Text = trackBarRightLevel.Value.ToString();
            }
        }

        private void UpdateATWhiteBalanceState(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            int awbState = 0;
            int grayState = 0;
            bool isGray = false;

            // Get the gray state
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_MONOCHROME, ref grayState))
            {
                if (1 == grayState)
                {
                    isGray = true;
                    checkBoxGray.Checked = true;
                    checkBoxAWB.Enabled = false;
                }
                else
                {
                    isGray = false;
                    checkBoxGray.Checked = false;
                    checkBoxAWB.Enabled = true;
                }
            }

            // Get current auto white balance status
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATWBALANCE, ref awbState))
            {
                if (awbState > 1)
                {
                    checkBoxAWB.Checked = true;

                    trackBarRed.Enabled = false;
                    labelNameRed.Enabled = false;
                    labelValueRed.Enabled = false;

                    trackBarGreen.Enabled = false;
                    labelNameGreen.Enabled = false;
                    labelValueGreen.Enabled = false;

                    trackBarBlue.Enabled = false;
                    labelNameBlue.Enabled = false;
                    labelValueBlue.Enabled = false;

                    trackBarColorTemperature.Enabled = false;
                    labelNameColorTemperature.Enabled = false;
                    labelValueColorTemperature.Enabled = false;
                }
                else
                {
                    trackBarRed.Enabled = !isGray;
                    labelNameRed.Enabled = !isGray;
                    labelValueRed.Enabled = !isGray;

                    trackBarGreen.Enabled = !isGray;
                    labelNameGreen.Enabled = !isGray;
                    labelValueGreen.Enabled = !isGray;

                    trackBarBlue.Enabled = !isGray;
                    labelNameBlue.Enabled = !isGray;
                    labelValueBlue.Enabled = !isGray;

                    trackBarColorTemperature.Enabled = m_isSupportCCT && !isGray;
                    labelNameColorTemperature.Enabled = m_isSupportCCT && !isGray;
                    labelValueColorTemperature.Enabled = m_isSupportCCT && !isGray;
                }
            }

            double channelValue = 0;
            // Get the current red channel value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref channelValue, 1))
            {
                trackBarRed.Value = (int)channelValue;
                channelValue /= 2.0f;
                labelValueRed.Text = channelValue.ToString("#0.0");
            }

            // Get the current green channel value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref channelValue, 2))
            {
                trackBarGreen.Value = (int)channelValue;
                channelValue /= 2.0f;
                labelValueGreen.Text = channelValue.ToString("#0.0");
            }

            // Get the current blue channel value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref channelValue, 3))
            {
                trackBarBlue.Value = (int)channelValue;
                channelValue /= 2.0f;
                labelValueBlue.Text = channelValue.ToString("#0.0");
            }

            UpdateColorTemperature(opCam);
/*
            // Get current color temperature value
            double cctValue = 0;
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CLRTEMPERATURE, ref cctValue, 0))
            {
                UpdateColorTemperatureValue(opCam, (int)cctValue, true);
            }
*/
        }

        private void UpdateRoiState(bool isRoi)
        {
            labelWidth.Enabled = !isRoi;
            labelHeight.Enabled = !isRoi;
            labelHOffset.Enabled = !isRoi;
            labelVOffset.Enabled = !isRoi;

            textBoxWidth.Enabled = !isRoi;
            textBoxHeight.Enabled = !isRoi;
            textBoxHOffset.Enabled = !isRoi;
            textBoxVOffset.Enabled = !isRoi;

            buttonRoi.Text = isRoi ? "Set Full" : "Set ROI";
        }

        private void UpdateColorTemperatureValue(TUCAM_OPEN opCam, int cctValue, bool isSetTrackBar)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            string textStr = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";

            TUCAM_VALUE_TEXT valueText;
            valueText.nID = (int)TUCAM_IDPROP.TUIDP_CLRTEMPERATURE;
            valueText.dbValue = cctValue;
            valueText.nTextSize = 32;
            valueText.pText = Marshal.StringToHGlobalAnsi(textStr);

            // Get color temperature value
            TUCamAPI.TUCAM_Prop_GetValueText(opCam.hIdxTUCam, ref valueText, 0);
            labelValueColorTemperature.Text = Marshal.PtrToStringAnsi(valueText.pText);

            if (isSetTrackBar)
            {
                trackBarColorTemperature.Value = cctValue;
            }
        }

        private void UpdateColorTemperature(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            double redChannel = 0;
            double greenChannel = 0;
            double blueChannel = 0;
            
            TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref redChannel, 1);         // Get the current red channel value
            TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref greenChannel, 2);       // Get the current green channel value
            TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref blueChannel, 3);        // Get the current blue channel value  

            UInt32 cctValue = 0;

            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Index_GetColorTemperature(opCam.hIdxTUCam, (Int32)redChannel, (Int32)greenChannel, (Int32)blueChannel, ref cctValue))
            {
                UpdateColorTemperatureValue(opCam, (int)cctValue, true);
            }
        }


        private void UpdateControlValue(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            int paramValue = 0;

            // Get the current resolution value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_RESOLUTION, ref paramValue))
            {
                comboBoxRes.SelectedIndex = paramValue;
            }

            // Get the current binning
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_BINNING_SUM, ref paramValue))
            {
                radioButton1x1.Checked = (1 == paramValue) ? true : false;
                radioButton2x2.Checked = (2 == paramValue) ? true : false;
                radioButton3x3.Checked = (3 == paramValue) ? true : false;
                radioButton4x4.Checked = (4 == paramValue) ? true : false;

                radioButton1x1.Enabled = true;
                radioButton2x2.Enabled = true;
                radioButton3x3.Enabled = true;
                radioButton4x4.Enabled = true;
            }
            else
            {
                radioButton1x1.Enabled = false;
                radioButton2x2.Enabled = false;
                radioButton3x3.Enabled = false;
                radioButton4x4.Enabled = false;
            }

            UpdateATExposureState(opCam);
        }

        private void UpdateBasicAdjustmentValue(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            double tmpValue = 0;
            double paramValue = 0;

            // Get the current gamma value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_GAMMA, ref paramValue, 0))
            {
                trackBarGamma.Value = (int)paramValue;
                tmpValue = paramValue / 100;
                labelValueGamma.Text = tmpValue.ToString("#0.00");
            }

            // Get the current contrast value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CONTRAST, ref paramValue, 0))
            {
                trackBarContrast.Value = (int)paramValue;
                labelValueContrast.Text = trackBarContrast.Value.ToString();
            }

            // Get the current sharpness value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_SHARPNESS, ref paramValue, 0))
            {
                trackBarSharpness.Value = (int)paramValue;
                labelValueSharpness.Text = trackBarSharpness.Value.ToString();
            }

            // Get the current sharpness value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_ENHANCE_STRENGTH, ref paramValue, 0))
            {
                trackBarPermeability.Value = (int)paramValue;
                labelValuePermeability.Text = trackBarPermeability.Value.ToString();
            }

            UpdateATLevelsState(opCam);
        }

        private void UpdateColorAdjustmentValue(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            double paramValue = 0;

            // Get the current saturation value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_SATURATION, ref paramValue, 0))
            {
                trackBarSaturation.Value = (int)paramValue;
                labelValueSaturation.Text = trackBarSaturation.Value.ToString();
            }

            // Get the current hue value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_HUE, ref paramValue, 0))
            {
                trackBarHue.Value = (int)paramValue;
                labelValueHue.Text = trackBarHue.Value.ToString();
            }

            // Get the current light value
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Prop_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_LIGHT, ref paramValue, 0))
            {
                trackBarLight.Value = (int)paramValue;
                labelValueLight.Text = trackBarLight.Value.ToString();
            }

            UpdateATWhiteBalanceState(opCam);
        }

        private void UpdateOtherValue(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            int paramValue = 0;

            // Get the current HDR state
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_HDR, ref paramValue))
            {
                checkBoxHdr.Checked = (1 == paramValue) ? true : false;
            }

            // Get the current horizontal state
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_HORIZONTAL, ref paramValue))
            {
                checkBoxHorizontal.Checked = (1 == paramValue) ? true : false;
            }

            // Get the current vertical state
            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Capa_GetValue(opCam.hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_VERTICAL, ref paramValue))
            {
                checkBoxVertical.Checked = (1 == paramValue) ? true : false;
            }
        }

        private void EnableTriggerControl(bool isEnabled)
        {
            groupBoxExpMode.Enabled = isEnabled;
            groupBoxEdgeMode.Enabled = isEnabled;
            groupBoxHardware.Enabled = isEnabled;
            groupBoxSoftwareTrigger.Enabled = isEnabled;

            labelNameDelay.Enabled = isEnabled;
            labelDelayUs.Enabled = isEnabled;
            labelDelayMs.Enabled = isEnabled;
            labelDelaySec.Enabled = isEnabled;

            numericUpDownDelayUs.Enabled = isEnabled;
            numericUpDownDelayMs.Enabled = isEnabled;
            numericUpDownDelaySec.Enabled = isEnabled;

            buttonDelayOK.Enabled = isEnabled;
            buttonTriggerSnap.Enabled = isEnabled;
            buttonTriggerApply.Enabled = isEnabled;
        }

        private void UpdateTriggerValue(TUCAM_OPEN opCam)
        {
            if (IntPtr.Zero == opCam.hIdxTUCam)
                return;

            if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Cap_GetTrigger(opCam.hIdxTUCam, ref m_triggerAttr))
            {
                EnableTriggerControl(true);

                UpdateDelayTime((UInt64)m_triggerAttr.nDelayTm);

                radioButtonOff.Checked = ((int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE == m_triggerAttr.nTgrMode) ? true : false;
                radioButtonStandard.Checked = ((int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_STANDARD == m_triggerAttr.nTgrMode) ? true : false;
                radioButtonSynchronization.Checked = ((int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_SYNCHRONOUS == m_triggerAttr.nTgrMode) ? true : false;
                radioButtonGlobal.Checked = ((int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_GLOBAL == m_triggerAttr.nTgrMode) ? true : false;
                checkBoxSoftwareTrigger.Checked = ((int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_SOFTWARE == m_triggerAttr.nTgrMode) ? true : false;

                if (m_triggerAttr.nTgrMode < (int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE || m_triggerAttr.nTgrMode > (int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_SOFTWARE)
                {
                    radioButtonOff.Checked = true;
                }

                bool isTimed = ((int)TUCAM_TRIGGER_EXP.TUCTE_EXPTM == m_triggerAttr.nExpMode) ? true : false;
                bool isRising = ((int)TUCAM_TRIGGER_EDGE.TUCTD_RISING == m_triggerAttr.nEdgeMode) ? true : false;
                bool isSupportDelay = ((int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_STANDARD == m_triggerAttr.nTgrMode && isTimed);
                
                radioButtonTimed.Checked = isTimed;
                radioButtonWidth.Checked = !isTimed;
                radioButtonRising.Checked = isRising;
                radioButtonFalling.Checked = !isRising;

                labelDelayUs.Enabled = isSupportDelay;
                labelDelayMs.Enabled = isSupportDelay;
                labelDelaySec.Enabled = isSupportDelay;
                labelNameDelay.Enabled = isSupportDelay;

                numericUpDownDelayUs.Enabled = isSupportDelay;
                numericUpDownDelayMs.Enabled = isSupportDelay;
                numericUpDownDelaySec.Enabled = isSupportDelay;

                buttonDelayOK.Enabled = isSupportDelay;

                radioButtonOff.Enabled = !checkBoxSoftwareTrigger.Checked;
                radioButtonStandard.Enabled = !checkBoxSoftwareTrigger.Checked;
                radioButtonSynchronization.Enabled = !checkBoxSoftwareTrigger.Checked;
                radioButtonGlobal.Enabled = !checkBoxSoftwareTrigger.Checked;

                radioButtonTimed.Enabled = (!checkBoxSoftwareTrigger.Checked && !radioButtonSynchronization.Checked && !radioButtonOff.Checked);
                radioButtonWidth.Enabled = (m_triggerAttr.nTgrMode > (int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE && m_triggerAttr.nTgrMode < (int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_SOFTWARE) ? true : false;
                radioButtonRising.Enabled = (m_triggerAttr.nTgrMode > (int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE && m_triggerAttr.nTgrMode < (int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_SOFTWARE) ? true : false;
                radioButtonFalling.Enabled = (m_triggerAttr.nTgrMode > (int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE && m_triggerAttr.nTgrMode < (int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_SOFTWARE) ? true : false;

                buttonTriggerApply.Enabled = true;
                checkBoxSoftwareTrigger.Enabled = true;
                buttonTriggerSnap.Enabled = checkBoxSoftwareTrigger.Checked;
            }
            else
            {
                EnableTriggerControl(false);
            }
        }

        private void comboBoxName_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (m_indexCam != comboBoxName.SelectedIndex)
            {
                UpdateInformation(m_opCamList[m_indexCam]);
                UpdateControlValue(m_opCamList[m_indexCam]);
                UpdateBasicAdjustmentValue(m_opCamList[m_indexCam]);
                UpdateColorAdjustmentValue(m_opCamList[m_indexCam]);
            }
        }

        private void comboBoxRes_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_RESOLUTION, comboBoxRes.SelectedIndex);

                m_isRoi = false;
                UpdateRoiState(m_isRoi);
            }
        }

        private void radioButton1x1_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_RESOLUTION, comboBoxRes.SelectedIndex);
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_BINNING_SUM, 1);

                m_isRoi = false;
                UpdateRoiState(m_isRoi);
            }
        }

        private void radioButton2x2_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_RESOLUTION, comboBoxRes.SelectedIndex);
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_BINNING_SUM, 2);

                m_isRoi = false;
                UpdateRoiState(m_isRoi);
            }
        }

        private void radioButton3x3_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_RESOLUTION, comboBoxRes.SelectedIndex);
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_BINNING_SUM, 3);

                m_isRoi = false;
                UpdateRoiState(m_isRoi);
            }
        }

        private void radioButton4x4_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_RESOLUTION, comboBoxRes.SelectedIndex);
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_BINNING_SUM, 4);

                m_isRoi = false;
                UpdateRoiState(m_isRoi);
            }
        }

        private void buttonLive_Click(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                if (m_isWaiting)
                {
                    StopWaitForFrame(m_opCamList[m_indexCam]);
                    buttonLive.Text = "Live";
                }
                else
                {
                    StartWaitForFrame(m_opCamList[m_indexCam]);
                    buttonLive.Text = "Stop";
                    drawingBox.Refresh();
                }

                EnablePanelByWaitingState(m_isWaiting);
            }
        }

        private void trackBarGain_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_GLOBALGAIN, (double)trackBarGain.Value, 0);
                labelValueGain.Text = trackBarGain.Value.ToString();
            }
        }

        private void checkBoxAE_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATEXPOSURE, (checkBoxAE.Checked ? 1 : 0));

                UpdateATExposureState(m_opCamList[m_indexCam]);

                if (checkBoxAE.Checked)
                {
                    m_aeTimer.Start();
                }
                else
                {
                    m_aeTimer.Stop();
                }
            }
        }

        private void buttonOnceAe_Click(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATEXPOSURE, 2);

                buttonOnceAe.Enabled = false;

                m_onceAeTimer.Start();
            }
        }

        private void trackBarTarget_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_BRIGHTNESS, (double)trackBarTarget.Value, 0);
                labelValueTarget.Text = trackBarTarget.Value.ToString();
            }
        }

        private void buttonExpOK_Click(object sender, EventArgs e)
        {
            UInt64 expValue = (UInt64)numericUpDownSec.Value * 1000 * 1000 + (UInt64)numericUpDownMs.Value * 1000 + (UInt64)numericUpDownUs.Value;

            if (PID_MICHROME5PRO == m_pid || PID_MICHROME6 == m_pid)
            {
                if (expValue < 137)
                    expValue = 130;

                if (expValue > 15000000)
                    expValue = 15000000;
            }

            if (m_opCamList.Count > 0)
            {
                double getExpValue = 0;
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_EXPOSURETM, (double)(expValue / 1000.0f), 0);
                TUCamAPI.TUCAM_Prop_GetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_EXPOSURETM, ref getExpValue, 0);
                Config.INI.WriteValue("device", "CAMERA_EXPOSURE", expValue.ToString());
                UpdateExposureTime((UInt64)(getExpValue * 1000));
            }
        }

        private void buttonCtrlDefault_Click(object sender, EventArgs e)
        {
            bool isWaiting = m_isWaiting;

            if (isWaiting)
            {
                StopWaitForFrame(m_opCamList[m_indexCam]);
            }

            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_RESOLUTION, m_resolutionCapa.nValDft);
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_BINNING_SUM, m_binningCapa.nValDft);
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATEXPOSURE, m_aeCapa.nValDft);

                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_GLOBALGAIN, m_gainProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_BRIGHTNESS, m_aeTargetProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_EXPOSURETM, m_exposureProp.dbValDft, 0);

                UpdateControlValue(m_opCamList[m_indexCam]);
            }

            if (isWaiting)
            {
                StartWaitForFrame(m_opCamList[m_indexCam]);
            }

            EnablePanelByWaitingState(m_isWaiting);
        }

        private void buttonBrowse_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBroeser = new FolderBrowserDialog();

            if (folderBroeser.ShowDialog() == DialogResult.OK)
            {
                m_filePath = folderBroeser.SelectedPath;
                textBoxPath.Text = m_filePath;
            }
        }

        private void checkBoxTiff_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxTiff.Checked)
            {
                m_savedFormat |= (int)(TUIMG_FORMATS.TUFMT_TIF);
                m_savedFormatCnt++;
            }
            else
            {
                if (m_savedFormatCnt <= 1)
                {
                    checkBoxTiff.Checked = true;
                }
                else
                {
                    m_savedFormat &= ~(int)(TUIMG_FORMATS.TUFMT_TIF);
                }
                
                m_savedFormatCnt--;
            }
        }

        private void checkBoxRaw_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxRaw.Checked)
            {
                m_savedFormat |= (int)(TUIMG_FORMATS.TUFMT_RAW);
                m_savedFormatCnt++;
            }
            else
            {
                if (m_savedFormatCnt <= 1)
                {
                    checkBoxRaw.Checked = true;
                }
                else
                {
                    m_savedFormat &= ~(int)(TUIMG_FORMATS.TUFMT_RAW);
                }
                                
                m_savedFormatCnt--;
            }
        }

        private void checkBoxJpg_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxJpg.Checked)
            {
                m_savedFormat |= (int)(TUIMG_FORMATS.TUFMT_JPG);
                m_savedFormatCnt++;
            }
            else
            {
                if (m_savedFormatCnt <= 1)
                {
                    checkBoxJpg.Checked = true;
                }
                else
                {
                    m_savedFormat &= ~(int)(TUIMG_FORMATS.TUFMT_JPG);
                }
                
                m_savedFormatCnt--;
            }
        }

        private void checkBoxPng_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxPng.Checked)
            {
                m_savedFormat |= (int)(TUIMG_FORMATS.TUFMT_PNG);
                m_savedFormatCnt++;
            }
            else
            {
                if (m_savedFormatCnt <= 1)
                {
                    checkBoxPng.Checked = true;
                }
                else
                {
                    m_savedFormat &= ~(int)(TUIMG_FORMATS.TUFMT_PNG);
                }
                
                m_savedFormatCnt--;
            }
        }

        private void checkBoxBmp_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxBmp.Checked)
            {
                m_savedFormat |= (int)(TUIMG_FORMATS.TUFMT_BMP);
                m_savedFormatCnt++;
            }
            else
            {
                if (m_savedFormatCnt <= 1)
                {
                    checkBoxBmp.Checked = true;
                }
                else
                {
                    m_savedFormat &= ~(int)(TUIMG_FORMATS.TUFMT_BMP);
                }
                
                m_savedFormatCnt--;
            }
        }

        private void buttonCapture_Click(object sender, EventArgs e)
        {
            if (m_isSaving)
            {
                m_isSaving = false;
                buttonRecord.Enabled = true;

                buttonCapture.Text = "Capture";
            }
            else
            {
                m_imageName = textBoxImageName.Text;
                m_totalFrames = Convert.ToInt32(textBoxTotalFrames.Text);

                if ("" == m_imageName)
                {
                    MessageBox.Show("Image name must be not empty!", "Tips");
                    return;
                }

                if (m_totalFrames < 1)
                {
                    MessageBox.Show("Total frames must more than 1!", "Tips");
                    return;
                }

                // Is directory exists
                if (!Directory.Exists(m_filePath))
                {
                    Directory.CreateDirectory(m_filePath, null);
                }

                m_captureTimes++;
                m_savedFramesCnt = 1;
                m_savedSucceedCnt = 0;

                m_isSaving = true;
                buttonRecord.Enabled = false;

                buttonCapture.Text = "Stop Capture";
            }
        }

        private void buttonRecord_Click(object sender, EventArgs e)
        {
            if (m_isRecording)
            {
                m_isRecording = false;
                buttonCapture.Enabled = true;

                TUCamAPI.TUCAM_Rec_Stop(m_opCamList[m_indexCam].hIdxTUCam);

                buttonRecord.Text = "Record";
            }
            else
            {
                // Is directory exists
                if (!Directory.Exists(m_filePath))
                {
                    Directory.CreateDirectory(m_filePath, null);
                }

                DateTime now = DateTime.Now;
                m_imageName = textBoxImageName.Text;
                string videoFileName = m_filePath + "\\" + m_imageName + "_" + now.Year.ToString() + now.Month.ToString("D2") + now.Day.ToString("D2") + now.Hour.ToString("D2") + now.Minute.ToString("D2") + now.Second.ToString("D2") + ".avi";

                TUCAM_REC_SAVE recSave;
                recSave.fFps = m_fps;
                recSave.nCodec = 0;
                recSave.pstrSavePath = Marshal.StringToHGlobalAnsi(videoFileName);

                if (TUCAMRET.TUCAMRET_SUCCESS == TUCamAPI.TUCAM_Rec_Start(m_opCamList[m_indexCam].hIdxTUCam, recSave))
                {
                    m_isRecording = true;
                    buttonCapture.Enabled = false;

                    buttonRecord.Text = "Stop Record";
                }
            }
        }

        private void buttonRoi_Click(object sender, EventArgs e)
        {
            bool isWaiting = m_isWaiting;

            if (isWaiting)
            {
                StopWaitForFrame(m_opCamList[m_indexCam]);
            }

            TUCAM_ROI_ATTR roiAttr;

            if (m_isRoi)
            {
                m_isRoi = false;

                roiAttr.bEnable = m_isRoi;
                roiAttr.nVOffset = 0;
                roiAttr.nHOffset = 0;
                roiAttr.nWidth = m_drawing.nSrcWidth;
                roiAttr.nHeight = m_drawing.nSrcHeight;

                TUCamAPI.TUCAM_Cap_SetROI(m_opCamList[m_indexCam].hIdxTUCam, roiAttr);
            }
            else
            {
                m_isRoi = true;

                roiAttr.bEnable = m_isRoi;
                roiAttr.nWidth = ((Convert.ToInt32(textBoxWidth.Text) >> 2) << 2);
                roiAttr.nHeight = ((Convert.ToInt32(textBoxHeight.Text) >> 2) << 2);
                roiAttr.nVOffset = ((Convert.ToInt32(textBoxVOffset.Text) >> 2) << 2);
                roiAttr.nHOffset = ((Convert.ToInt32(textBoxHOffset.Text) >> 2) << 2);

                TUCamAPI.TUCAM_Cap_SetROI(m_opCamList[m_indexCam].hIdxTUCam, roiAttr);
                TUCamAPI.TUCAM_Cap_GetROI(m_opCamList[m_indexCam].hIdxTUCam, ref roiAttr);

                textBoxWidth.Text = roiAttr.nWidth.ToString();
                textBoxHeight.Text = roiAttr.nHeight.ToString();
                textBoxHOffset.Text = roiAttr.nHOffset.ToString();
                textBoxVOffset.Text = roiAttr.nVOffset.ToString();
            }

            UpdateRoiState(m_isRoi);
          
            if (isWaiting)
            {
                StartWaitForFrame(m_opCamList[m_indexCam]);
            }

            drawingBox.Refresh();
        }

        private void checkBoxLeftLevel_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                int autoLeftLevels = checkBoxLeftLevel.Checked ? 1 : 0;
                int autoRightLevels = checkBoxRightLevel.Checked ? 1 : 0;
                int autoLevels = (autoRightLevels << 1) | autoLeftLevels;

                if (0 != autoLevels)
                {
                    TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_HISTC, 1);
                }
                else
                {
                    TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_HISTC, 0);
                }

                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATLEVELS, autoLevels);

                if (checkBoxLeftLevel.Checked)
                {
                    m_autoLeftLevelsTimer.Start();

                    trackBarLeftLevel.Enabled = false;
                    labelNameLeftLevel.Enabled = false;
                    labelValueLeftLevel.Enabled = false;
                }
                else
                {
                    m_autoLeftLevelsTimer.Stop();

                    trackBarLeftLevel.Enabled = true;
                    labelNameLeftLevel.Enabled = true;
                    labelValueLeftLevel.Enabled = true;

                    TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_LFTLEVELS, m_leftLevelProp.dbValDft, 0);
                    trackBarLeftLevel.Value = (int)m_leftLevelProp.dbValDft;
                    labelValueLeftLevel.Text = trackBarLeftLevel.Value.ToString();
                }                
            }
        }

        private void checkBoxRightLevel_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                int autoLeftLevels = checkBoxLeftLevel.Checked ? 1 : 0;
                int autoRightLevels = checkBoxRightLevel.Checked ? 1 : 0;
                int autoLevels = (autoRightLevels << 1) | autoLeftLevels;

                if (0 != autoLevels)
                {
                    TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_HISTC, 1);
                }
                else
                {
                    TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_HISTC, 0);
                }

                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATLEVELS, autoLevels);

                if (checkBoxRightLevel.Checked)
                {
                    m_autoRightLevelsTimer.Start();

                    trackBarRightLevel.Enabled = false;
                    labelNameRightLevel.Enabled = false;
                    labelValueRightLevel.Enabled = false;
                }
                else
                {
                    m_autoRightLevelsTimer.Stop();

                    trackBarRightLevel.Enabled = true;
                    labelNameRightLevel.Enabled = true;
                    labelValueRightLevel.Enabled = true;

                    TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_RGTLEVELS, m_rightLevelProp.dbValDft, 0);
                    trackBarRightLevel.Value = (int)m_rightLevelProp.dbValDft;
                    labelValueRightLevel.Text = trackBarRightLevel.Value.ToString();
                }
            }
        }

        private void trackBarLeftLevel_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                int leftLevel = trackBarLeftLevel.Value;
                int righttLevel = trackBarRightLevel.Value;

                if (leftLevel >= righttLevel)
                {
                    righttLevel = leftLevel + 1;
                    trackBarRightLevel.Value = righttLevel;
                    labelValueRightLevel.Text = righttLevel.ToString();
                }

                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_LFTLEVELS, (double)trackBarLeftLevel.Value, 0);
                labelValueLeftLevel.Text = trackBarLeftLevel.Value.ToString();
            }
        }

        private void trackBarRightLevel_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                int leftLevel = trackBarLeftLevel.Value;
                int righttLevel = trackBarRightLevel.Value;

                if (leftLevel >= righttLevel)
                {
                    leftLevel = righttLevel - 1;
                    leftLevel = leftLevel < 0 ? 0 : leftLevel;
                    trackBarLeftLevel.Value = leftLevel;
                    labelValueLeftLevel.Text = leftLevel.ToString();
                }

                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_RGTLEVELS, (double)trackBarRightLevel.Value, 0);
                labelValueRightLevel.Text = trackBarRightLevel.Value.ToString();
            }
        }

        private void trackBarGamma_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                double gammaValue = trackBarGamma.Value / 100.0f;
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_GAMMA, (double)trackBarGamma.Value, 0);
                labelValueGamma.Text = gammaValue.ToString("#0.00");
            }
        }

        private void trackBarContrast_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CONTRAST, (double)trackBarContrast.Value, 0);
                labelValueContrast.Text = trackBarContrast.Value.ToString();
            }
        }

        private void trackBarSharpness_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_SHARPNESS, (double)trackBarSharpness.Value, 0);
                labelValueSharpness.Text = trackBarSharpness.Value.ToString();
            }
        }

        private void trackBarPermeability_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_ENHANCE_STRENGTH, (double)trackBarPermeability.Value, 0);
                labelValuePermeability.Text = trackBarPermeability.Value.ToString();
            }
        }


        private void checkBoxGray_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_MONOCHROME, checkBoxGray.Checked ? 1 : 0);

                UpdateATWhiteBalanceState(m_opCamList[m_indexCam]);
            }
        }

        private void checkBoxAWB_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                if (checkBoxAWB.Checked)
                {
                    TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATWBALANCE, 2);

                    m_awbTimer.Start();
                }
                else
                {
                    TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATWBALANCE, 0);

                    m_awbTimer.Stop();
                }

                UpdateATWhiteBalanceState(m_opCamList[m_indexCam]);
            }
        }

        private void buttonOnceWB_Click(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATWBALANCE, 1);

                m_onceWbTimer.Start();
            }
        }

        private void trackBarRed_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, (double)trackBarRed.Value, 1);
                labelValueRed.Text = trackBarRed.Value.ToString();

                UpdateColorTemperature(m_opCamList[m_indexCam]);
            }
        }

        private void trackBarGreen_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, (double)trackBarGreen.Value, 2);
                labelValueGreen.Text = trackBarGreen.Value.ToString();

                UpdateColorTemperature(m_opCamList[m_indexCam]);
            }
        }

        private void trackBarBlue_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, (double)trackBarBlue.Value, 3);
                labelValueBlue.Text = trackBarBlue.Value.ToString();

                UpdateColorTemperature(m_opCamList[m_indexCam]);
            }
        }

        private void trackBarColorTemperature_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                IntPtr hIdxTUCam = m_opCamList[m_indexCam].hIdxTUCam;

                TUCamAPI.TUCAM_Prop_SetValue(hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CLRTEMPERATURE, (double)trackBarColorTemperature.Value, 0);
                UpdateColorTemperatureValue(m_opCamList[m_indexCam], trackBarColorTemperature.Value, false);

                double channelValue = 0.0f;
                TUCamAPI.TUCAM_Prop_GetValue(hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref channelValue, 1);
                trackBarRed.Value = (int)channelValue;
                channelValue /= 2.0f;
                labelValueRed.Text = channelValue.ToString("#0.0");

                TUCamAPI.TUCAM_Prop_GetValue(hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref channelValue, 2);
                trackBarGreen.Value = (int)channelValue;
                channelValue /= 2.0f;
                labelValueGreen.Text = channelValue.ToString("#0.0");

                TUCamAPI.TUCAM_Prop_GetValue(hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, ref channelValue, 3);
                trackBarBlue.Value = (int)channelValue;
                channelValue /= 2.0f;
                labelValueBlue.Text = channelValue.ToString("#0.0");
            }
        }

        private void trackBarSaturation_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_SATURATION, (double)trackBarSaturation.Value, 0);
                labelValueSaturation.Text = trackBarSaturation.Value.ToString();
            }
        }

        private void trackBarHue_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_HUE, (double)trackBarHue.Value, 0);
                labelValueHue.Text = trackBarHue.Value.ToString();
            }
        }

        private void trackBarLight_Scroll(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_LIGHT, (double)trackBarLight.Value, 0);
                labelValueLight.Text = trackBarLight.Value.ToString();
            }
        }

        private void buttonAdjustDefault_Click(object sender, EventArgs e)
        {
            bool isWaiting = m_isWaiting;

            if (isWaiting)
            {
                StopWaitForFrame(m_opCamList[m_indexCam]);
            }

            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_MONOCHROME, m_monochromeCapa.nValDft);
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATLEVELS, m_autoLevelsCapa.nValDft);
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_ATWBALANCE, m_awbCapa.nValDft);
  
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_LFTLEVELS, m_leftLevelProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_RGTLEVELS, m_rightLevelProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_GAMMA, m_gammaProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CONTRAST, m_contrastProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_SHARPNESS, m_sharpnessProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_ENHANCE_STRENGTH, m_permeabilityProp.dbValDft, 0);

                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, m_redChannelProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, m_greenChannelProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_CHNLGAIN, m_blueChannelProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_SATURATION, m_saturationProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_HUE, m_hueProp.dbValDft, 0);
                TUCamAPI.TUCAM_Prop_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDPROP.TUIDP_LIGHT, m_lightProp.dbValDft, 0);

                UpdateBasicAdjustmentValue(m_opCamList[m_indexCam]);
                UpdateColorAdjustmentValue(m_opCamList[m_indexCam]);
            }

            if (isWaiting)
            {
                StartWaitForFrame(m_opCamList[m_indexCam]);
            }
        }

        private void checkBoxHdr_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_HDR, (checkBoxHdr.Checked ? 1 : 0));
            }
        }

        private void checkBoxHorizontal_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_HORIZONTAL, (checkBoxHorizontal.Checked ? 1 : 0));
            }
        }

        private void checkBoxVertical_CheckedChanged(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Capa_SetValue(m_opCamList[m_indexCam].hIdxTUCam, (int)TUCAM_IDCAPA.TUIDC_VERTICAL, (checkBoxVertical.Checked ? 1 : 0));
            }
        }

        private string GetCurrentParameterTeam()
        {
            string paramTeam = "A";

            if (radioButtonParamB.Checked)
            {
                paramTeam = "B";
            }
            else if (radioButtonParamC.Checked)
            {
                paramTeam = "C";
            }
            else if (radioButtonParamD.Checked)
            {
                paramTeam = "D";
            }

            return paramTeam;
        }

        private void buttonParamSave_Click(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_File_SaveProfiles(m_opCamList[m_indexCam].hIdxTUCam, Marshal.StringToHGlobalAnsi(GetCurrentParameterTeam()));
            }
        }

        private void buttonParamLoad_Click(object sender, EventArgs e)
        {
            bool isWaiting = m_isWaiting;

            if (isWaiting)
            {
                StopWaitForFrame(m_opCamList[m_indexCam]);
            }

            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_File_LoadProfiles(m_opCamList[m_indexCam].hIdxTUCam, Marshal.StringToHGlobalAnsi(GetCurrentParameterTeam()));

                UpdateControlValue(m_opCamList[m_indexCam]);
                UpdateBasicAdjustmentValue(m_opCamList[m_indexCam]);
                UpdateColorAdjustmentValue(m_opCamList[m_indexCam]);
                UpdateOtherValue(m_opCamList[m_indexCam]);
            }

            if (isWaiting)
            {
                StartWaitForFrame(m_opCamList[m_indexCam]);
            }
        }

        private void radioButtonOff_CheckedChanged(object sender, EventArgs e)
        {
            checkBoxSoftwareTrigger.Checked = false;
            m_triggerAttr.nTgrMode = (int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE;

            radioButtonTimed.Enabled = false;
            radioButtonWidth.Enabled = false;
            radioButtonRising.Enabled = false;
            radioButtonFalling.Enabled = false;
            
            labelDelayUs.Enabled = false;
            labelDelayMs.Enabled = false;
            labelDelaySec.Enabled = false;
            labelNameDelay.Enabled = false;

            numericUpDownDelayUs.Enabled = false;
            numericUpDownDelayMs.Enabled = false;
            numericUpDownDelaySec.Enabled = false;

            buttonDelayOK.Enabled = false;
        }

        private void radioButtonStandard_CheckedChanged(object sender, EventArgs e)
        {
            checkBoxSoftwareTrigger.Checked = false;
            m_triggerAttr.nTgrMode = (int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_STANDARD;

            radioButtonTimed.Enabled = true;
            radioButtonWidth.Enabled = true;
            radioButtonRising.Enabled = true;
            radioButtonFalling.Enabled = true;

            labelDelayUs.Enabled = radioButtonTimed.Checked;
            labelDelayMs.Enabled = radioButtonTimed.Checked;
            labelDelaySec.Enabled = radioButtonTimed.Checked;
            labelNameDelay.Enabled = radioButtonTimed.Checked;

            numericUpDownDelayUs.Enabled = radioButtonTimed.Checked;
            numericUpDownDelayMs.Enabled = radioButtonTimed.Checked;
            numericUpDownDelaySec.Enabled = radioButtonTimed.Checked;

            buttonDelayOK.Enabled = radioButtonTimed.Checked;
        }

        private void radioButtonSynchronization_CheckedChanged(object sender, EventArgs e)
        {
            checkBoxSoftwareTrigger.Checked = false;
            m_triggerAttr.nTgrMode = (int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_SYNCHRONOUS;
            m_triggerAttr.nExpMode = (int)TUCAM_TRIGGER_EXP.TUCTE_WIDTH;

            radioButtonWidth.Checked = true;
            radioButtonTimed.Checked = false;

            radioButtonTimed.Enabled = false;
            radioButtonWidth.Enabled = true;
            radioButtonRising.Enabled = true;
            radioButtonFalling.Enabled = true;

            labelDelayUs.Enabled = false;
            labelDelayMs.Enabled = false;
            labelDelaySec.Enabled = false;
            labelNameDelay.Enabled = false;

            numericUpDownDelayUs.Enabled = false;
            numericUpDownDelayMs.Enabled = false;
            numericUpDownDelaySec.Enabled = false;

            buttonDelayOK.Enabled = false;
        }

        private void radioButtonGlobal_CheckedChanged(object sender, EventArgs e)
        {
            checkBoxSoftwareTrigger.Checked = false;
            m_triggerAttr.nTgrMode = (int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_GLOBAL;

            radioButtonTimed.Enabled = true;
            radioButtonWidth.Enabled = true;
            radioButtonRising.Enabled = true;
            radioButtonFalling.Enabled = true;

            labelDelayUs.Enabled = false;
            labelDelayMs.Enabled = false;
            labelDelaySec.Enabled = false;
            labelNameDelay.Enabled = false;

            numericUpDownDelayUs.Enabled = false;
            numericUpDownDelayMs.Enabled = false;
            numericUpDownDelaySec.Enabled = false;

            buttonDelayOK.Enabled = false;
        }

        private void radioButtonTimed_CheckedChanged(object sender, EventArgs e)
        {
            m_triggerAttr.nExpMode = (int)TUCAM_TRIGGER_EXP.TUCTE_EXPTM;

            radioButtonTimed.Enabled = !radioButtonGlobal.Checked;
            radioButtonWidth.Enabled = !radioButtonGlobal.Checked;
            radioButtonRising.Enabled = !radioButtonGlobal.Checked;
            radioButtonFalling.Enabled = !radioButtonGlobal.Checked;

            labelDelayUs.Enabled = !radioButtonGlobal.Checked;
            labelDelayMs.Enabled = !radioButtonGlobal.Checked;
            labelDelaySec.Enabled = !radioButtonGlobal.Checked;
            labelNameDelay.Enabled = !radioButtonGlobal.Checked;

            numericUpDownDelayUs.Enabled = !radioButtonGlobal.Checked;
            numericUpDownDelayMs.Enabled = !radioButtonGlobal.Checked;
            numericUpDownDelaySec.Enabled = !radioButtonGlobal.Checked;

            buttonDelayOK.Enabled = !radioButtonGlobal.Checked;
        }

        private void radioButtonWidth_CheckedChanged(object sender, EventArgs e)
        {
            m_triggerAttr.nExpMode = (int)TUCAM_TRIGGER_EXP.TUCTE_WIDTH;

            labelDelayUs.Enabled = false;
            labelDelayMs.Enabled = false;
            labelDelaySec.Enabled = false;
            labelNameDelay.Enabled = false;

            numericUpDownDelayUs.Enabled = false;
            numericUpDownDelayMs.Enabled = false;
            numericUpDownDelaySec.Enabled = false;

            buttonDelayOK.Enabled = false;
        }

        private void radioButtonRising_CheckedChanged(object sender, EventArgs e)
        {
            m_triggerAttr.nEdgeMode = (int)TUCAM_TRIGGER_EDGE.TUCTD_RISING;
        }

        private void radioButtonFalling_CheckedChanged(object sender, EventArgs e)
        {
            m_triggerAttr.nEdgeMode = (int)TUCAM_TRIGGER_EDGE.TUCTD_FAILING;
        }

        private void checkBoxSoftwareTrigger_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxSoftwareTrigger.Checked)
            {
                m_triggerAttr.nTgrMode = (int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_SOFTWARE;
            }
            else
            {
                m_triggerAttr.nTgrMode = (int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE;

                radioButtonOff.Checked = true;
                radioButtonStandard.Checked = false;
                radioButtonSynchronization.Checked = false;
                radioButtonGlobal.Checked = false;
            }

            radioButtonOff.Enabled = !checkBoxSoftwareTrigger.Checked;
            radioButtonStandard.Enabled = !checkBoxSoftwareTrigger.Checked;
            radioButtonSynchronization.Enabled = !checkBoxSoftwareTrigger.Checked;
            radioButtonGlobal.Enabled = !checkBoxSoftwareTrigger.Checked;
            radioButtonTimed.Enabled = !checkBoxSoftwareTrigger.Checked;
            radioButtonWidth.Enabled = !checkBoxSoftwareTrigger.Checked;
            radioButtonRising.Enabled = !checkBoxSoftwareTrigger.Checked;
            radioButtonFalling.Enabled = !checkBoxSoftwareTrigger.Checked;

            labelDelayUs.Enabled = !checkBoxSoftwareTrigger.Checked;
            labelDelayMs.Enabled = !checkBoxSoftwareTrigger.Checked;
            labelDelaySec.Enabled = !checkBoxSoftwareTrigger.Checked;
            labelNameDelay.Enabled = !checkBoxSoftwareTrigger.Checked;

            numericUpDownDelayUs.Enabled = !checkBoxSoftwareTrigger.Checked;
            numericUpDownDelayMs.Enabled = !checkBoxSoftwareTrigger.Checked;
            numericUpDownDelaySec.Enabled = !checkBoxSoftwareTrigger.Checked;

            buttonDelayOK.Enabled = !checkBoxSoftwareTrigger.Checked;
        }

        private void buttonTriggerSnap_Click(object sender, EventArgs e)
        {
            if (m_opCamList.Count > 0)
            {
                TUCamAPI.TUCAM_Cap_DoSoftwareTrigger(m_opCamList[m_indexCam].hIdxTUCam);
            }
        }

        private void buttonDelayOK_Click(object sender, EventArgs e)
        {
            UInt64 delayTime = (UInt64)numericUpDownDelaySec.Value * 1000 * 1000 + (UInt64)numericUpDownDelayMs.Value * 1000 + (UInt64)numericUpDownDelayUs.Value;

            UpdateDelayTime(delayTime);
        }

        private void buttonTriggerApply_Click(object sender, EventArgs e)
        {
            UInt64 delayTime = (UInt64)numericUpDownDelaySec.Value * 1000 * 1000 + (UInt64)numericUpDownDelayMs.Value * 1000 + (UInt64)numericUpDownDelayUs.Value;

            UpdateDelayTime(delayTime);

            buttonTriggerApply.Enabled = false;
            EnableTriggerControl(false);
        
            if (m_isWaiting)
            {
                StopWaitForFrame(m_opCamList[m_indexCam]);
            }

            if ((int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE < m_triggerAttr.nTgrMode && m_triggerAttr.nTgrMode < (int)TUCAM_CAPTURE_MODES.TUCCM_TRIGGER_SOFTWARE)
            {
                m_triggerAttr.nFrames = -1;   // To RAM
            }

            if ((int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE != m_triggerAttr.nTgrMode)
            {
                buttonLive.Enabled = false;
                m_isTrigger = true;
            }
            else
            {
                buttonLive.Enabled = true;
                m_isTrigger = false;
            }

            TUCamAPI.TUCAM_Cap_SetTrigger(m_opCamList[m_indexCam].hIdxTUCam, m_triggerAttr);

            if ((int)TUCAM_CAPTURE_MODES.TUCCM_SEQUENCE != m_triggerAttr.nTgrMode)
            {
                m_savedSucceedCnt = 0;
                m_captureTimes = (1 == m_savedFramesCnt) ? m_captureTimes : ++m_captureTimes;
                m_savedFramesCnt = 1;

                StartWaitForFrame(m_opCamList[m_indexCam]);
            }

            buttonTriggerApply.Enabled = true;
            UpdateTriggerValue(m_opCamList[m_indexCam]);
             
        }

        private void button2_Click(object sender, EventArgs e)
        {
           /* OpenFileDialog fileDia = new OpenFileDialog();
            fileDia.Multiselect = false;//不允许多选
            fileDia.Title = "选择图样";//设置弹窗标题
            fileDia.Filter = "图片（*.jpg）|*.jpg";//设定可选的文件类型
            fileDia.InitialDirectory = Application.StartupPath + "\\image\\paterns";//设置初始的文件夹位置

            if (fileDia.ShowDialog() == DialogResult.OK)
            {
                Console.WriteLine("-----------------------" + fileDia.FileName);
                HeHeOcr hh = new HeHeOcr();
                aireturn.Text=hh.GetHehe(fileDia.FileName);
            }*/
        }
    }
}
